/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package genomemap.data;

import commons.util.FreqDist;

import genomemap.map.ProbeMap;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Genetic and physical data on multiple chromosomes of an organism, as specified by Dr. Arnold, for
 * creating integration maps. The data have the following features: <ul> <li>All the clones have the
 * same length.</li> </ul> <p> This data is immutable. </p>
 *
 * @author Susanta Tewari
 * @version Nov 13, 2011
 * @since Aug 20, 2010
 */
public interface OrganismData {

    /**
     * All the clones have the same length.
     *
     * @return the clone length (KB)
     */
    int getCloneLength();

    /**
     * Linkage groups of the genome available for analysis.
     *
     * @return an unmodifiable set of linkage groups available for analysis
     */
    Set<Integer> getLinkageGroups();

    /**
     * Genes for the specified linkage group in the order present in the data.
     *
     * @param linkageGroup linkage group
     * @return an unmodifiable list of genes in the same order as in data for the specified linkage
     *         group
     * @throws IllegalArgumentException if <code> getLinkageGroups().contains(linkageGroup) </code>
     * returns false
     */
    List<String> genes(Integer linkageGroup);

    /**
     * Clones for the specified linkage group in the data.
     *
     * @param linkageGroup linkage group
     * @return an unmodifiable list of clones in the same order as in data for the specified linkage
     *         group
     * @throws IllegalArgumentException if <code> getLinkageGroups().contains(linkageGroup) </code>
     * returns false
     */
    Set<String> clones(Integer linkageGroup);

    /**
     * Probes for the specified linkage group in the order present in the data.
     *
     * @param linkageGroup linkage groups
     * @return an unmodifiable list of probes in the same order as in data for the specified linkage
     *         group
     * @throws IllegalArgumentException if <code> getLinkageGroups().contains(linkageGroup) </code>
     * returns false
     */
    List<String> probes(Integer linkageGroup);

    /**
     * Hybridization data for the given order of probes. In the returned array the rows indicate
     * clones and the columns probes.
     *
     * @param linkageGroup linkage group
     * @param probes probes contained in getProbes() or {@code null} to indicate all probes
     * @return a copy of hybridization data for all the clones given by <code>clones(linkageGroup)</code>
     *         and the the specified order of probes
     * @throws IllegalArgumentException If <li> <code> getLinkageGroups().contains(linkageGroup)
     * </code> returns false and/or <li> <code> probes(linkageGroup).containsAll(probes) </code>
     * returns false;
     */
    KSA00Data createKSA00Data(Integer linkageGroup, List<String> probes);

    /**
     * Provides genotype data for the given order of genes. The rows indicate offsprings and the
     * columns genes.
     *
     * @param linkageGroup linkage group
     * @param genes genes contained in getGenes() or {@code null} to indicate all genes
     * @return a copy of genotype data for all the offsprings and the specified order of genes
     * @throws IllegalArgumentException <li> <code> getLinkageGroups().contains(linkageGroup)
     * </code> returns false and/or <li> <code> genes(linkageGroup).containsAll(genes) </code>
     * returns false;
     */
    TAB08Data createTAB08Data(Integer linkageGroup, List<String> genes);
}
